﻿#include "MaterialGraphLinkViewModel.h"

#include "MaterialGraphLinkModel.h"

#include "MaterialGraph/MaterialGraphViewModel.h"
#include "MaterialGraph/Pin/MaterialGraphPinViewModel.h"

#include "Math/Math.h"

void RMaterialGraphLinkViewModel::BindModel(
        TSharedObjectPtr<RMaterialGraphLinkModel> InModel
        ,TSharedObjectPtr<RMaterialGraphViewModel> InGraphViewModel
        )
{
    BaseModel=InModel;

    StartPin = InGraphViewModel->FindPinViewModelByModel(InModel->Start);
    EndPin = InGraphViewModel->FindPinViewModelByModel(InModel->End);
}

bool RMaterialGraphLinkViewModel::IsHidden() const
{
    return !BaseModel->IsValid();
}

float RMaterialGraphLinkViewModel::GetStartXInGraphSpace() const
{
    return StartPin->GetCenterXInGraphWidget();
}

float RMaterialGraphLinkViewModel::GetStartYInGraphSpace() const
{
    return StartPin->GetCenterYInGraphWidget();
}

float RMaterialGraphLinkViewModel::GetEndXInGraphSpace() const
{
    return EndPin->GetCenterXInGraphWidget();
}

float RMaterialGraphLinkViewModel::GetEndYInGraphSpace() const
{
    return EndPin->GetCenterYInGraphWidget();
}

SColor RMaterialGraphLinkViewModel::GetStartColor() const
{
    return StartPin->GetPinColor();
}

SColor RMaterialGraphLinkViewModel::GetEndColor() const
{
    return EndPin->GetPinColor();
}

TVector<SVec2> RMaterialGraphLinkViewModel::CalculateLinkingPoints(const SVec2 &Start, const SVec2 &End)
{
    TVector<SVec2> Points;

    //这条线被拆分为三段
    // 第一段（p0,p1,p2）是贝塞尔曲线
    // 第二段（p2,p3）是直线
    // 第三段（p3,p4,p5）是贝塞尔曲线

    //第一段
    // 起点P0，中间点P1 终点P2，
    SVec2 P0,P1,P2,P3,P4,P5;
    P0=Start;
    P5=End;
    
    //P1 在起点的右边
    P1.X=P0.X +//CMath::Abs(End.X-Start.X)*0.2f;
        CMath::Min(CMath::Abs(End.X-Start.X)*0.2f,50);
    P1.Y=P0.Y;

    //p4 在终点的左边
    P4.X=P5.X - //CMath::Abs(End.X-Start.X)*0.2f;
        CMath::Min(CMath::Abs(End.X-Start.X)*0.2f,50);
    P4.Y=P5.Y;

    //p2 和 p3 在 线段（p1，p4)上
    const float T=.2f;
    P2.X=(1-T)*P1.X+T*P4.X;
    P2.Y=(1-T)*P1.Y+T*P4.Y;

    P3.X=(1-T)*P4.X+T*P1.X;
    P3.Y=(1-T)*P4.Y+T*P1.Y;

    Points.Add(Start);

    //贝塞尔曲线
    for(int64_t Index=1; Index<10; Index++)
    {
        float T=Index*0.1f;
        float OneMinusT=1-T;
        SVec2 Point;
        Point.X=OneMinusT*OneMinusT*P0.X+2*OneMinusT*T*P1.X+T*T*P2.X;
        Point.Y=OneMinusT*OneMinusT*P0.Y+2*OneMinusT*T*P1.Y+T*T*P2.Y;

        Points.Add(Point);
    }

    //直线
    Points.Add(P3);

    //贝塞尔曲线
    for(int64_t Index=1; Index<10; Index++)
    {
        float T=Index*0.1f;
        float OneMinusT=1-T;
        SVec2 Point;
        Point.X=OneMinusT*OneMinusT*P3.X+2*OneMinusT*T*P4.X+T*T*P5.X;
        Point.Y=OneMinusT*OneMinusT*P3.Y+2*OneMinusT*T*P4.Y+T*T*P5.Y;
        
        Points.Add(Point);
    }

    Points.Add(End);

    return Points;
}
